package com.worldwind.test;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import com.R;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import gov.nasa.worldwind.BasicWorldWindowController;
import gov.nasa.worldwind.PickedObject;
import gov.nasa.worldwind.PickedObjectList;
import gov.nasa.worldwind.shape.Highlightable;
import gov.nasa.worldwind.shape.Label;
import gov.nasa.worldwind.shape.Path;
import gov.nasa.worldwind.shape.Placemark;
import gov.nasa.worldwind.shape.Polygon;

/**
 * Created by Lenovo on 2018/4/21.
 */

public class PickObjectController extends BasicWorldWindowController {

    protected Object pickedObject;          // last picked object from onDown events

    protected Object selectedObject;        // last "selected" object from single tap
    protected Context context;

    public PickObjectController(Context context) {
        this.context = context;
    }

    /**
     * Assign a subclassed SimpleOnGestureListener to a GestureDetector to handle the "pick" events.
     */
    protected GestureDetector pickGestureDetector = new GestureDetector(
            context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onDown(MotionEvent event) {
            pick(event);    // Pick the object(s) at the tap location
            return false;   // By not consuming this event, we allow it to pass on to the navigation gesture handlers
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            toggleSelection();  // Highlight the picked object
            // By not consuming this event, we allow the "up" event to pass on to the navigation gestures,
            // which is required for proper zoom gestures.  Consuming this event will cause the first zoom
            // gesture to be ignored.  As an alternative, you can implement onSingleTapConfirmed and consume
            // event as you would expect, with the trade-off being a slight delay tap response.
            return false;
        }
    });

    /**
     * Delegates events to the pick handler or the native World Wind navigation handlers.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Allow pick listener to process the event first.
        boolean consumed = this.pickGestureDetector.onTouchEvent(event);

        // If event was not consumed by the pick operation, pass it on the globe navigation handlers
        if (!consumed) {

            // The super class performs the pan, tilt, rotate and zoom
            return super.onTouchEvent(event);
        }
        return consumed;
    }

    /**
     * Performs a pick at the tap location.
     */
    public void pick(MotionEvent event) {
        // Forget our last picked object
        this.pickedObject = null;

        // Perform a new pick at the screen x, y
        PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY());

        // Get the top-most object for our new picked object
        PickedObject topPickedObject = pickList.topPickedObject();
        if (topPickedObject != null) {
            this.pickedObject = topPickedObject.getUserObject();
        }
    }

    /**
     * Toggles the selected state of a picked object.
     */
    public void toggleSelection() {

        // Display the highlight or normal attributes to indicate the
        // selected or unselected state respectively.
        if (pickedObject instanceof Highlightable) {

            // Determine if we've picked a "new" object so we know to deselect the previous selection
            boolean isNewSelection = pickedObject != this.selectedObject;

            // Only one object can be selected at time, deselect any previously selected object
            if (isNewSelection && this.selectedObject instanceof Highlightable) {
                ((Highlightable) this.selectedObject).setHighlighted(false);
            }

            // Show the selection by showing its highlight attributes
            ((Highlightable) pickedObject).setHighlighted(isNewSelection);
            this.getWorldWindow().requestRedraw();

            // Track the selected object
            this.selectedObject = isNewSelection ? pickedObject : null;

            showAttributeDialog();//show attribute if selectObject not null
        }
    }

    public void showAttributeDialog(){
        //关键问题是如何从pickobject中得到我们设置的要素属性数据呢？
        //把数据存在要素的useProperties属性中，然后就能在查询时获取了
       final ArrayList<String> items =  new ArrayList<>();
        if(selectedObject!=null){
            if(selectedObject instanceof Placemark){
                Placemark selectedPlacemark = (Placemark)selectedObject;
                //for getting  keys ,i add getter to get useProperty in AbstractRenderable
                // warning: can't keep the order of attributes:无法保证属性显示的顺序与表结构一致
                Set<Object> keys = selectedPlacemark.getUserProperties().keySet();
                Iterator<Object> iterator = keys.iterator();
                while (iterator.hasNext()) {
                    String key =iterator.next().toString();
                    String value = selectedPlacemark.getUserProperty(key).toString();
                    items.add( key+":"+ value);
                }
            }else if(selectedObject instanceof Path){
                Path selectedPolyline = (Path) selectedObject;
                Set<Object> keys = selectedPolyline.getUserProperties().keySet();
                Iterator<Object> iterator = keys.iterator();
                while (iterator.hasNext()) {
                    String key =iterator.next().toString();
                    String value = selectedPolyline.getUserProperty(key).toString();
                    items.add( key+":"+ value);
                }
            }else if(selectedObject instanceof Polygon){
                Polygon selectedPolygon = (Polygon)selectedObject;
                Set<Object> keys = selectedPolygon.getUserProperties().keySet();
                Iterator<Object> iterator = keys.iterator();
                while (iterator.hasNext()) {
                    String key =iterator.next().toString();
                    String value = selectedPolygon.getUserProperty(key).toString();
                    items.add( key+":"+ value);
                }
            }else if(selectedObject instanceof Label){
              return;
            }

            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("要素属性信息")
                    .setAdapter(new ArrayAdapter<String>(context, R.layout.array_item, items), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(context,"你选中了《"+items.get(which)+"》",Toast.LENGTH_SHORT).show();
                        }
                    })
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(context,"单击了［确定］按钮",Toast.LENGTH_SHORT).show();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(context,"单击了［取消］按钮",Toast.LENGTH_SHORT).show();
                        }
                    })
                    .create()
                    .show();
        }

    }
}